from rest_framework import serializers
from apps.czb.models import Orders as CzbOrder
from .models import YLProgramRecord, YLPayRecord
from .client import ProgramPay
from .client import YLClient

yl_client = YLClient()

yl_program_pay = ProgramPay()
from finance_c2c.settings import orderModel


# 申请支付链接（H5支付）
class YLPaySerializers(serializers.Serializer):
    supply_id = serializers.CharField(write_only=True, label="提交订单时返回的订单id",
                                      error_messages={"blank": "订单supply_id不能为空"}, help_text="系统内部订单id")
    redirect_url = serializers.CharField(write_only=True, label="重定向结果页面的url", required=True,
                                         error_messages={"blank": "重定向结果页面不能为空"}, help_text="前端重定向链接")
    pay_order_model = serializers.ChoiceField(write_only=True, required=False, allow_null=True, choices=orderModel,
                                              label="支付订单类型")
    # pay_type = 1 h5支付  2小程序支付  3 app支付
    pay_type = serializers.IntegerField(write_only=True, required=False, allow_null=True, label="付款方式")

    def validate_supply_id(self, attrs):
        if self.context["request"].POST.get("pay_order_model") == "czb":
            czb_order_instance = CzbOrder.objects.get(id=attrs)
            setattr(self, "czb_order_instance", czb_order_instance)
            if czb_order_instance.result == 1:
                serializers.ValidationError("已经支付过了")
            if czb_order_instance.result == 2:
                serializers.ValidationError("此订单已退款，请重新下单")
            if czb_order_instance.result == 3:
                serializers.ValidationError("此订单有误，请重新下单")
            if czb_order_instance.result == 101:
                serializers.ValidationError("此订单已取消，请重新下单")
        return attrs

    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        pass


# 小程序支付
class MiniSerializers(YLPaySerializers):
    def validate(self, attrs):
        attrs = super(MiniSerializers, self).validate(attrs)
        pay_type = self.initial_data["pay_type"]
        if pay_type in ["wx.appPreOrder", "wx.unifiedOrder", "trade.precreate", "qmf.order"]:
            return attrs
        else:
            raise serializers.ValidationError("pay_type 字段错误")

    def create(self, validated_data):
        czb_order_instance = self.czb_order_instance
        msgType = self.initial_data["msgType"]
        user = self.context["request"].user
        totalAmount = czb_order_instance.payment
        # 整理参数
        if msgType == "trade.create":
            user_id = user.wx_user.openid
            parameters = yl_program_pay.get_pay_parameters(msgType, totalAmount, openid=user_id)
        else:
            user_id = 123
            parameters = yl_program_pay.get_pay_parameters(msgType, totalAmount, ali_user_id=user_id)
        # 创建数据
        instance = YLProgramRecord.objects.create_base(parameters)
        # 请求接口
        kwargs, response = yl_program_pay.pay(parameters)
        # 更新数据
        instance.update_response(response)
        # 更新 czb_order_instance
        czb_order_instance.out_trade_no = parameters.get("merOrderId")
        czb_order_instance.save()
        return response


# 统一下单
class WeChatOrdeSerializer(serializers.Serializer):
    orderNo = serializers.CharField(required=True, allow_null=False, label="订单号", help_text="订单号", write_only=True)
    redirect_url = serializers.CharField(write_only=True, label="重定向结果页面的url", required=True,
                                         error_messages={"blank": "重定向结果页面不能为空"}, help_text="前端重定向链接")
    model = serializers.ChoiceField(write_only=True, required=False, allow_null=True, choices=orderModel,
                                              label="支付订单类型")

    def validate_model(self, model):
        if model == "coffee":
            return model
        else:
            raise serializers.ValidationError("参数错误")

    def validate_orderNo(self, orderNo):
        model = self.initial_data["model"]
        if model == "coffee":
            from apps.coffee.models import CoffeeOrder
            try:
                order = CoffeeOrder.objects.get(orderNo=orderNo)
            except Exception as e:
                raise serializers.ValidationError("订单号错误")
        else:
            raise serializers.ValidationError("参数错误")
        if order.out_trade_no:
            out_trade_no = order.out_trade_no
            if YLPayRecord.objects.filter(out_trade_no=out_trade_no).exists():
                pay_record = YLPayRecord.objects.get(out_trade_no=out_trade_no)
                if pay_record.is_pay:
                    raise serializers.ValidationError("此订单已经支付成功")
                last_num = out_trade_no[-1]
                if last_num == "9":
                    raise serializers.ValidationError("此订单已经锁定，清重新下单")
                if last_num.isdigit():
                    last_num = str(int(last_num) + 1)
                    n = 1
                else:
                    n = 0
                    last_num = "0"
                out_trade_no = out_trade_no[:len(out_trade_no) - n] + last_num
        else:
            out_trade_no = YLClient().new_unique_value
        order.out_trade_no = out_trade_no
        order.save()
        return order

    def create(self, validated_data):
        model = validated_data["model"]
        order = validated_data["orderNo"]
        redirect_url = validated_data["redirect_url"]
        out_trade_no = order.out_trade_no
        # 初始化
        totalAmount = 0
        srcReserve = ""
        orderDesc = ""
        if model == "coffee":
            totalAmount = order.payment
            srcReserve = "coffee"
            orderDesc = "咖啡支付"
        else:
            pass
        pay_url, out_trade_no = YLClient().pay(srcReserve, orderDesc, totalAmount, redirect_url,
                                               merOrderId=out_trade_no)
        instance = YLPayRecord.objects.create_record(totalAmount, out_trade_no, srcReserve=srcReserve)
        return pay_url, instance

    class Meta:
        fields = ("orderNo", "redirect_url", "model")
